﻿
namespace TestClient.MVC.Controllers
{
	#region Using Directives
	using System;
	using System.Configuration;
	using System.Globalization;
	using System.Web.Mvc;
	using Microsoft.WindowsAzure;
	using Microsoft.WindowsAzure.StorageClient;
	#endregion

	#region HomeController
	/// <summary>
	/// The Home Controller.
	/// </summary>
	public class HomeController : Controller
	{
		#region Constants
		/// <summary>
		/// Configuration section key containing the name of the Container where to upload files
		/// </summary>
		private const string ContainerNameKey = "ContainerName";
		/// <summary>
		/// Configuration section key containing connection string.
		/// </summary>
		private const string ConfigurationSectionKey = "StorageAccountConfiguration";
		/// <summary>
		/// Configuration section key containing sas timeout.
		/// </summary>
		private const string SASTimeoutKey = "SASTimeout";
		#endregion

		#region Views

		public ActionResult Index()
		{
			ViewBag.Message = "Welcome to ASP.NET MVC!";

			return View();
		}

		public ActionResult About()
		{
			return View();
		}

		public ActionResult Interlink()
		{
			return View();
		}

		#endregion

		#region Azure
		/// <summary>
		/// Called from JS to initialize the Azure Connection
		/// </summary>
		/// <returns>A JSON Result containing the Service Uri and ClientConfig.</returns>
		[HttpPost]
		public JsonResult InitAzureConfig()
		{
			var timeout = int.Parse(ConfigurationManager.AppSettings[SASTimeoutKey]);
			var account = CloudStorageAccount.Parse(ConfigurationManager.AppSettings[ConfigurationSectionKey]);
			var containerName = ConfigurationManager.AppSettings[ContainerNameKey];
			containerName = containerName.ToLowerInvariant(); // Azure requires container names to be lower case.

			var blobs = account.CreateCloudBlobClient();

			// Ensure clientaccesspolicy
			HomeController.CreateSilverlightPolicy(blobs);

			// Init Container
			var container = blobs.GetContainerReference(containerName);
			container.CreateIfNotExist();
			var sas = container.GetSharedAccessSignature(new SharedAccessPolicy()
			{
				// Read required to get existing metadata
				Permissions = SharedAccessPermissions.Read | SharedAccessPermissions.Write,
				SharedAccessExpiryTime = DateTime.UtcNow + TimeSpan.FromMinutes(timeout)
			});

			// Generate ServiceUri
			var service = (new UriBuilder(container.Uri)
			{
				Query = sas.TrimStart('?')
			}).Uri.AbsoluteUri;

			// Generate ClientConfig
			var expires = TimeSpan.FromMinutes(timeout).TotalSeconds.ToString(CultureInfo.CurrentCulture);
			var chunk = container.ServiceClient.WriteBlockSizeInBytes.ToString(CultureInfo.CurrentCulture);
			var config = string.Format("timeout={0},maxChunkSize={1}", expires, chunk);

			return Json(new { serviceUri = service, clientConfig = config });
		}

		/// <summary>
		/// Creates the silverlight policy file in storage account.
		/// </summary>
		/// <param name="client">The blob client.</param>
		private static void CreateSilverlightPolicy(CloudBlobClient client)
		{
			var container = client.GetContainerReference("$root");
			if (container.CreateIfNotExist())
			{
				container.SetPermissions(new BlobContainerPermissions()
					{
						PublicAccess = BlobContainerPublicAccessType.Blob
					});
				var blob = client.GetBlobReference("clientaccesspolicy.xml");
				blob.Properties.ContentType = "text/xml";
				blob.UploadText(@"<?xml version=""1.0"" encoding=""utf-8""?>
                    <access-policy>
                      <cross-domain-access>
                        <policy>
                          <allow-from http-methods=""*"" http-request-headers=""*"">
                            <domain uri=""*"" />
                            <domain uri=""http://*"" />
                          </allow-from>
                          <grant-to>
                            <resource path=""/"" include-subpaths=""true"" />
                          </grant-to>
                        </policy>
                      </cross-domain-access>
                    </access-policy>");
			}
		}

		#endregion
	}
	#endregion
}